package com.ruben;

import org.thymeleaf.util.ListUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.IntFunction;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @ClassName: CollectionDemo
 * @Description:
 * @Date: 2020/9/8 19:55
 * *
 * @author: achao<achao1441470436 @ gmail.com>
 * @version: 1.0
 * @since: JDK 1.8
 */
public class CollectionDemo {
    private static final int COUNT = 100 * 100 * 100;

    public static void main(String[] args) {
        List<Integer> integerList = Arrays.stream(new int[]{1, 2, 3}).boxed().collect(Collectors.toList());
        List<Integer> collect = Stream.concat(integerList.stream(), integerList.stream()).collect(Collectors.toList());
        collect.forEach(System.out::print);
        System.out.println();
        collect = Stream.of(integerList, integerList).flatMap(List::stream).collect(Collectors.toList());
        collect.forEach(System.out::print);
        System.out.println();
        Collections.shuffle(collect);
    }

    private static void toQuadraticElementArray() {
        int[][] array = new int[][]{{1, 2}, {1, 3, 3, 4}, {2, 3}};
        List<List<Integer>> collect = Arrays.stream(array).map(a1 -> Arrays.stream(a1).boxed().collect(Collectors.toList())).collect(Collectors.toList());
        array = collect.stream().map(integers -> integers.stream().mapToInt(value -> value).toArray()).toArray(int[][]::new);

        for (int[] ints : array) {
            for (int anInt : ints) {
                System.out.print(anInt + " ");
            }
            System.out.println();
        }
    }

    private static void picture() {
        // 原有数据库里的图片
        String pic = "http://p16.qhimg.com/bdm/960_593_0/t0195d14f593431562a.jpg;" +
                "http://p18.qhimg.com/bdm/480_296_0/t014a0ca534d64adbba.jpg;" +
                "http://p18.qhimg.com/bdm/480_296_0/t014a0ca534d64adbba.jpg;" +
                "http://p18.qhimg.com/bdm/480_296_0/t014a0ca534d64adbba.jpg";
        // 需要追加的图片
        String appendPic = "http://p19.qhimg.com/bdm/960_593_0/t01b24e85dc07d47b0d.jpg";
        // 现在做一个操作，追加并去重，转换成String
        // 一开始我想着用“;”分割，转换成list 然后追加、去重，再转换成原来格式的String（每张图片用“;”分割）
        // 用“;”分割成数组并转换成List
        List<String> picList = Arrays.asList(pic.split(";"));
        // 添加元素
        picList.add(appendPic);
        // 去重，转换成String，并且中间用“;”分割
        pic = picList.stream().distinct().collect(Collectors.joining(";"));
        // 输出结果
        System.out.println(pic);
        // 后来发现报了个 UnsupportedOperationException，瞬间想起来！
        // asList的返回对象是一个Arrays的内部类，它并没有实现集合个数的相关修改方法！
        // 所以改成了这种方式
        // 直接在字符串后追加“;”和图片url
        pic = pic.concat(";").concat(appendPic);
        // 用“;”分割成数组并转换成List,去重后再转换为String，用“;”分隔
        pic = Arrays.stream(pic.split(";")).distinct().collect(Collectors.joining(";"));
        // 输出结果
        System.out.println(pic);
    }

    private static void cat() {
        List<Animal> animal = new ArrayList<Animal>();
        List<Cat> cat = new ArrayList<Cat>();
        List<Garfield> garfield = new ArrayList<Garfield>();
        animal.add(new Animal());
        cat.add(new Cat());
        garfield.add(new Garfield());
//        List<? extends Cat> extendsCatFromAnimal = animal;
        List<? super Cat> superCatFromAnimal = animal;
        List<? extends Cat> extendsCatFromCat = cat;
        List<? super Cat> superCatFromCat = cat;
        List<? extends Cat> extendsCatFromGarfield = garfield;
//        List<? super Cat> superCatFromGarfield = garfield;
//        extendsCatFromCat.add(new Animal());
//        extendsCatFromCat.add(new Cat());
//        extendsCatFromCat.add(new Garfield());
//        superCatFromCat.add(new Animal());
        superCatFromCat.add(new Cat());
        superCatFromCat.add(new Garfield());
        Object catExtends2 = extendsCatFromCat.get(0);
        Cat catExtends1 = extendsCatFromCat.get(0);
//        Garfield garfield1 = extendsCatFromGarfield.get(0);
    }

    private static void timeCost() {
        List<Double> list = new ArrayList<>(COUNT);
        for (int i = 0; i < COUNT; i++) {
            list.add(i * 1.0);
        }
        long start = System.nanoTime();
        Double[] notEnoughArray = new Double[COUNT - 1];
        list.toArray(notEnoughArray);
        long middle1 = System.nanoTime();
        Double[] equalArray = new Double[COUNT];
        list.toArray(equalArray);
        long middle2 = System.nanoTime();
        Double[] doubleArray = new Double[COUNT * 2];
        list.toArray(doubleArray);
        long middle3 = System.nanoTime();
        list.toArray(new Double[0]);
        long end = System.nanoTime();
        long notEnoughArrayTime = middle1 - start;
        long equalArrayTime = middle2 - middle1;
        long doubleArrayTime = middle3 - middle2;
        long zeroArrayTime = end - middle2;
        System.out.println("数组容量小于集合大小：notEnoughArrayTime：" + notEnoughArrayTime / (1000.0 * 1000.0) + " ms");
        System.out.println("数组容量等于集合大小：：equalArrayTime：" + equalArrayTime / (1000.0 * 1000.0) + " ms");
        System.out.println("数组容量是集合的两倍：doubleArrayTime：" + doubleArrayTime / (1000.0 * 1000.0) + " ms");
        System.out.println("数组容量传入0：zeroArrayTime：" + zeroArrayTime / (1000.0 * 1000.0) + " ms");
    }

    private static void toArray() {
        List<String> list = new ArrayList<>(3);
        list.add("one");
        list.add("two");
        list.add("three");

        Object[] array = list.toArray();
        String[] array1 = list.toArray(new String[3]);

        String[] array2 = new String[2];
        list.toArray(array2);
        System.out.println(Arrays.asList(array2));

        String[] array3 = new String[3];
        list.toArray(array3);
        System.out.println(Arrays.asList(array3));
    }

    /**
     * 事实证明，可以通过 set（）方法修改元素的值，原有数组相应位置的值
     * 同时也会被修改，但是不能进行修改元素个数的任何操作，否则均会抛出
     * UnsupportedOperationException 异常。
     * Arrays asList 体现的是适配器模式，后台的数据
     * 仍是原有数组，set（）方法即闯接对数组进行值的修改操作。 asList的返回对象是一个
     * Arrays的内部类，它并没有实现集合个数的相关修改方法，这也正是抛出异常的原因。
     */
    private static void cannotModifyArray() {
        String[] stringArray = new String[3];
        stringArray[0] = "one";
        stringArray[1] = "two";
        stringArray[2] = "three";

        List<String> stringList = Arrays.asList(stringArray);
        stringList.set(0, "oneList");
        stringList.forEach(System.out::println);
        System.out.println("-----------");
        for (String s : stringArray) {
            System.out.println(s);
        }

        // 以下三行代码编译正确，但都会抛出运行时异常
        stringList.add("four");
        stringList.remove(2);
        stringList.clear();
    }

    static class Animal {
    }

    static class Cat extends Animal {

    }

    static class Garfield extends Cat {

    }
}
